package com.nervenets.web.hibernate;


import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate5.HibernateCallback;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;

/**
 * HIBERNATE 基础DAO类
 *
 * @author Administrator
 */
public abstract class BaseDao {
    @Resource
    private JdbcTemplate jdbcTemplate;
    @Resource
    private HibernateTemplate hibernateTemplate;

    @Transactional
    public void saveOrUpdate(DomainObject domainObject) {
        hibernateTemplate.saveOrUpdate(domainObject);
    }

    public void saveOrUpdate(DomainObject... domainObjects) {
        for (DomainObject domainObject : domainObjects) {
            if (null != domainObject) saveOrUpdate(domainObject);
        }
    }

    @Transactional
    public void delete(DomainObject object) {
        if (object != null) {
            hibernateTemplate.delete(object);
        }
    }

    public void deleteAll(Collection elements) {
        hibernateTemplate.deleteAll(elements);
    }

    public <T extends DomainObject> T findById(final long id, final Class<T> clazz) {
        if (0 == id) {
            return null;
        }
        return hibernateTemplate.execute(new HibernateCallback<T>() {
            @Override
            public T doInHibernate(Session session) throws HibernateException {
                Query query = session.createQuery("from " + clazz.getSimpleName() + " do where do.id = :id and removed = 0");
                query.setParameter("id", id);
                query.setCacheable(true);
                return (T) query.uniqueResult();
            }
        });
    }

    public <T extends DomainObject> T findByIdIgnoreRemoved(final long id, final Class<T> clazz) {
        if (0 == id) {
            return null;
        }
        return hibernateTemplate.execute(new HibernateCallback<T>() {
            @Override
            public T doInHibernate(Session session) throws HibernateException {
                Query query = session.createQuery("from " + clazz.getSimpleName() + " do where do.id = :id ");
                query.setParameter("id", id);
                query.setCacheable(true);
                return (T) query.uniqueResult();
            }
        });
    }

    @SuppressWarnings({"unchecked"})
    public <T extends DomainObject> List loadAll(Class<T> clazz) {
        return hibernateTemplate.find("from " + clazz.getName() + " where removed = 0");
    }

    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }

    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }
}
